package com.sneakxy.mybatis.commons.repository.config;

import java.util.List;
import java.util.Optional;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;

import com.sneakxy.mybatis.commons.config.SqlSessionFactoryConfiguer;
import com.sneakxy.mybatis.commons.properties.SpringDataMybatisProperties;
import com.sneakxy.mybatis.commons.utils.SnowflakeIdGenerator;

/**
 * @author 潜行的青衣
 */
public class MybatisSqlSessionFactoryBean extends SqlSessionFactoryBean {

	private SpringDataMybatisProperties springDataMybatisProperties;
	
	private List<SqlSessionFactoryConfiguer> sqlSessionFactoryConfiguers;
	
	private SnowflakeIdGenerator snowflakeIdGenerator;
	
	@Override
	protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
		MybatisCommonsConfiguration configuration = (MybatisCommonsConfiguration) FieldUtils.readField(this, "configuration", true);
		
		if(configuration == null) {
			configuration = new MybatisCommonsConfiguration();
			setConfiguration(configuration);
		}
		configuration.setSnowflakeIdGenerator(getSnowflakeIdGenerator());
		configuration.setObjectFactory(MybatisCommonsObjectFactory.getMybatisCommonsObjectFactory());
		if(springDataMybatisProperties != null) {
			configuration.setDialect(springDataMybatisProperties.resolveDialect(configuration));
			Optional.ofNullable(springDataMybatisProperties.getJdbcTypeForNull()).ifPresent(configuration::setJdbcTypeForNull);
		}
		if(sqlSessionFactoryConfiguers != null) {
			sqlSessionFactoryConfiguers.forEach((configur) -> {
				configur.configure(this);
			});
		}
		return super.buildSqlSessionFactory();
	}

	public SpringDataMybatisProperties getSpringDataMybatisProperties() {
		return springDataMybatisProperties;
	}

	public void setSpringDataMybatisProperties(SpringDataMybatisProperties springDataMybatisProperties) {
		this.springDataMybatisProperties = springDataMybatisProperties;
	}

	public List<SqlSessionFactoryConfiguer> getSqlSessionFactoryConfiguers() {
		return sqlSessionFactoryConfiguers;
	}

	public void setSqlSessionFactoryConfiguers(List<SqlSessionFactoryConfiguer> sqlSessionFactoryConfiguers) {
		this.sqlSessionFactoryConfiguers = sqlSessionFactoryConfiguers;
	}

	public SnowflakeIdGenerator getSnowflakeIdGenerator() {
		return snowflakeIdGenerator;
	}

	public void setSnowflakeIdGenerator(SnowflakeIdGenerator snowflakeIdGenerator) {
		this.snowflakeIdGenerator = snowflakeIdGenerator;
	}

}
